package com.med.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.med.config.AlipayConfig;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @BelongsProject: RuoYi-Vue
 * @BelongsPackage: com.ruoyi.controller
 * @Author: 泽日
 * @CreateTime: 2025-08-21 10:38
 * @Description: 支付宝支付接口控制器
 * 负责处理支付宝支付相关的请求，包括发起支付和接收支付结果回调
 * @Version: 1.0
 */
@RestController
@RequestMapping("/alipay") // 所有接口的基础路径
public class AliPayController {

    // 注入支付宝配置类，包含应用ID、密钥等关键配置
    @Resource
    private AlipayConfig aliPayConfig;

    /**
     * 支付宝支付结果异步通知接口
     * 支付宝在用户支付完成后会主动调用此接口，告知支付结果
     * @param request 包含支付宝回调参数的请求对象
     * @return "success"表示处理成功，"fail"表示处理失败（支付宝会重试失败的通知）
     * @throws AlipayApiException 支付宝接口调用异常
     */
    @RequestMapping("/notify")
    public String notify(HttpServletRequest request) throws AlipayApiException {
        // 用于存储支付宝回调的参数键值对
        Map<String, String> params = new HashMap<>();

        // 获取请求中所有参数（原始格式为Map<String, String[]>）
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            StringBuilder valueStr = new StringBuilder();
            // 将参数数组拼接为字符串（多值参数用逗号分隔）
            for (int i = 0; i < values.length; i++) {
                valueStr.append(i == values.length - 1 ? values[i] : values[i] + ",");
            }
            // 存入参数Map，用于后续签名验证
            params.put(name, valueStr.toString());
        }

        // 打印回调参数，方便开发调试
        System.out.println("支付宝回调参数：" + params);

        // 验证支付宝签名，确保请求来自支付宝且未被篡改
        boolean signVerified = AlipaySignature.rsaCheckV1(
                params,                      // 待验证的参数Map
                aliPayConfig.getAlipayPublicKey(),  // 支付宝公钥（用于验签）
                aliPayConfig.getCharset(),    // 字符编码（如UTF-8）
                aliPayConfig.getSignType()    // 签名算法类型（如RSA2）
        );

        if (signVerified) {
            // 签名验证成功，处理业务逻辑
            String outTradeNo = params.get("out_trade_no"); // 获取商户系统生成的订单号
            String tradeStatus = params.get("trade_status"); // 获取交易状态（如TRADE_SUCCESS表示支付成功）

            // 判断交易状态是否为支付成功或交易完成
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                // 支付成功，此处应处理订单状态更新、库存扣减等核心业务
                System.out.println("支付成功，订单号：" + outTradeNo);
                // TODO: 实际项目中需添加订单状态更新逻辑（如调用Service层方法）
            }
            return "success"; // 返回"success"告知支付宝已处理成功，无需重试
        } else {
            // 签名验证失败，可能是非法请求
            System.err.println("支付宝签名验证失败！");
            System.err.println("返回的参数：" + params); // 输出参数方便排查问题
            return "fail"; // 返回"fail"告知支付宝处理失败，支付宝会重试通知
        }
    }

    /**
     * 发起支付宝支付请求
     * 生成支付页面的HTML代码，前端可通过此代码跳转到支付宝支付页面
     * @param params 包含支付相关参数（如amount支付金额、userId用户ID）
     * @return 包含支付结果的Map，success为true时返回支付页面HTML
     * @throws Exception 可能的异常（如支付宝接口调用失败）
     */
    @RequestMapping("/payBalance")
    public Map<String, Object> payBalance(@RequestBody Map<String, String> params) throws Exception {
        String amount = params.get("amount");  // 从请求参数中获取支付金额（单位：元，精确到分）
        String userId = params.get("userId");  // 获取用户ID（可用于关联订单与用户，根据业务需求使用）

        // 创建支付宝客户端实例，用于调用支付宝接口
        AlipayClient alipayClient = new DefaultAlipayClient(
                aliPayConfig.getGatewayUrl(),    // 支付宝网关地址（如沙箱环境或正式环境）
                aliPayConfig.getAppId(),         // 应用ID（从支付宝开放平台获取）
                aliPayConfig.getAppPrivateKey(), // 应用私钥（商户自己的私钥，用于签名请求）
                "json",                          // 请求数据格式
                aliPayConfig.getCharset(),       // 字符编码
                aliPayConfig.getAlipayPublicKey(),// 支付宝公钥（用于验证支付宝返回的签名）
                aliPayConfig.getSignType()       // 签名算法类型（如RSA2）
        );

        // 用于存储返回给前端的结果
        Map<String, Object> result = new HashMap<>();
        // 生成唯一订单号（前缀+时间戳，确保不重复）
        String orderNo = "RECHARGE" + System.currentTimeMillis();

        // 创建支付请求模型，设置订单相关信息
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setOutTradeNo(orderNo);  // 设置商户订单号（唯一标识一笔订单）
        model.setTotalAmount(amount);  // 设置支付金额（字符串类型，如"0.01"表示1分钱）
        model.setSubject("充值账单");   // 订单标题（显示在支付宝支付页面）
        model.setProductCode("FAST_INSTANT_TRADE_PAY");  // 产品码，固定值（即时到账交易）

        // 创建支付请求对象，设置回调地址等信息
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setReturnUrl(aliPayConfig.getReturnUrl());  // 同步回调地址（支付完成后跳转的页面）
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());  // 异步通知地址（支付结果通知接口，即当前类的/notify方法）
        request.setBizModel(model);  // 设置订单模型

        // 调用支付宝接口，发起支付请求
        AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "POST");

        if (response.isSuccess()) {
            // 支付请求成功，支付宝返回支付页面的HTML代码
            result.put("success", true);
            result.put("payHtml", response.getBody());  // 支付页面HTML，前端可直接渲染或跳转
        } else {
            // 支付请求失败（如参数错误、签名失败等）
            result.put("success", false);
            result.put("msg", "支付请求失败");
        }

        return result;
    }
}